<?php
/**
 * User: lsp
 * Date: 2017/03/19
 * Time: 14:23
 */
header("Content-Type: text/html; charset=UTF-8");
include_once 'wx_api/Lib/public_number_third_party_platform/wxBizMsgCrypt.php';
class WechatThirdPlatform{
  //1、推送component_verify_ticket协议
  // 检验消息的真实性，并且获取解密后的明文
  public static function encrypt_msg($component_appid,$oldmsg){
        $third_platform_info = self::get_third_platform($component_appid);
        $pc = new \WXBizMsgCrypt($third_platform_info['token'], $third_platform_info['EncodingAESKey'],$third_platform_info['appid']);
        $msg = '';
        $timeStamp = time();
        $nonce=WeixinApi::createNonceStr();
        $pc->encryptMsg($oldmsg, $timeStamp, $nonce, $msg);
        return $msg;
    }

  // @return: result，code=1为成功失败返回对应的错误码
  public static   function decrypt_msg($component_appid_param){
    $result = array();
    $result['code'] = 0;
    $param = $_GET;
    log::write('param33333:'.json_encode($param));
    $encryptMsg = file_get_contents('php://input', 'r');
    if($encryptMsg && trim($encryptMsg) != ''){
      $msg_sign  = $param['msg_signature'];
      $timeStamp = $param['timestamp'];
      $nonce     = $param['nonce'];
      log::write('接收到的推送信息为333：'.$encryptMsg);

      $xml_tree = new \DOMDocument();
      $xml_tree->loadXML($encryptMsg);
      $array_component_appid = $xml_tree->getElementsByTagName('AppId');
      if($array_component_appid){
        $component_appid = $array_component_appid->item(0)->nodeValue;

      }
       if(!$component_appid){
          $component_appid = $component_appid_param;
        }

      $third_platform_info = self::get_third_platform($component_appid);
      log::write('从xml获取到的component_appid为'.$component_appid);

      $pc = new \WXBizMsgCrypt($third_platform_info['token'], $third_platform_info['EncodingAESKey'],$third_platform_info['appid']);
      $msg = '';
      $errCode = $pc->decryptMsg($msg_sign, $timeStamp, $nonce, $encryptMsg, $msg);
      log::write('msg='.$msg);
       $result['appid'] = $component_appid;

    if($errCode == 0){
       $result['code'] = 1;
       $result['msg'] = $msg;
    }
   }

    return $result;
  }
  //处理第三方通知的消息类型
  public static function deal_biz($msg,$result){
        // $result = array();
        $xml_tree = new \DOMDocument();
        $xml_tree->loadXML($msg);
        $array_info_type = $xml_tree->getElementsByTagName('InfoType');
        if($array_info_type){
          $info_type = $array_info_type->item(0)->nodeValue;
        }

        $result['info_type'] = $info_type;


        switch ($info_type) {
          case 'component_verify_ticket':
          $result = self::deal_component_verify_ticket($xml_tree,$result);
          break;
          case 'authorized':

          $result = self::deal_authorized($xml_tree,$result);
          break;
          case 'unauthorized':
          $result = self::deal_unauthorized($xml_tree,$result);
          break;
          case 'updateauthorized':
          $result = self::deal_authorized($xml_tree,$result);
          break;

          default:
          $result['msg'] = $msg;
          break;
        }
       return $result;

  }
  //处理数据类型为：updateauthorized的数据
  // public function deal_updateauthorized($xml_tree,$result){
  //   Log::write('进入处理deal_updateauthorized方法');
    // return $result;
  // }
   //处理数据类型为：authorized的数据
  private static  function deal_unauthorized($xml_tree,$result){
   Log::write('进入处理deal_unauthorized方法');
   $array_authorizer_appid = $xml_tree->getElementsByTagName('AuthorizerAppid');
   $authorizer_appid = $array_authorizer_appid->item(0)->nodeValue;
   $result['authorizer_appid'] = $authorizer_appid;
   return $result;
 }
  //处理数据类型为：authorized的数据
 private static function deal_authorized($xml_tree,$result){
   Log::write('进入处理deal_authorized方法');
   $array_auth_code = $xml_tree->getElementsByTagName('AuthorizationCode');
   $auth_code  = $array_auth_code->item(0)->nodeValue;
   $component_appid = $result['appid'];
   $array_authorizer_appid = $xml_tree->getElementsByTagName('AuthorizerAppid');
   $authorizer_appid = $array_authorizer_appid->item(0)->nodeValue;
   $result['authorization_info'] = self::get_authorizer_info($component_appid,$auth_code);
   $result['authorizer_info_base'] = self::get_authorization_base_info($component_appid,$authorizer_appid);
   $result['authorizer_appid'] = $authorizer_appid;
   $result['query_auth_code'] = $auth_code;
   return $result;
 }

  //获取（刷新）授权公众号的接口调用凭据（令牌）
  // @param component_appid: 第三方平台的appid，不传值，则默认一个
   // @param authorizer_appid: 公众号的appid，必传
   // @param authorizer_refresh_token:  公众号的刷新token，必传
  // @return json，新的authorizer_access_token，刷新authorizer_refresh_token
 public static function refresh_access_token($component_appid,$authorizer_appid,$authorizer_refresh_token){
   $component_appid = self::check_component_appid($component_appid);
   $component_access_token = self::get_component_access_token($component_appid);
   $url = 'https://api.weixin.qq.com/cgi-bin/component/api_authorizer_token?component_access_token='.$component_access_token;
   $post_data = array();
   $post_data['component_appid'] = $component_appid;
   $post_data['authorizer_appid'] = $authorizer_appid;
   $post_data['authorizer_refresh_token'] = $authorizer_refresh_token;
   $res = json_decode(self::post($url,json_encode($post_data)));
   Log::write('刷新access_token数据：'.json_encode($res));
   return $res;

 }
    //处理数据类型为：component_verify_ticket的数据
 private static function deal_component_verify_ticket($xml_tree,$result){
   $array_component_verify_ticket = $xml_tree->getElementsByTagName('ComponentVerifyTicket');
   $component_verify_ticket = $array_component_verify_ticket->item(0)->nodeValue;

   if($component_verify_ticket){
     $update_data = array();
     $update_data['component_verify_ticket'] = $result['component_verify_ticket'] = $component_verify_ticket;
     $update_data['appid'] = $result['appid'];
     self::update_third_platform($update_data);
     Log::write('解密获得的component_verify_ticket：'.$component_verify_ticket);
     echo 'success';
   }
   return $result;
 }
  //2、获取第三方平台component_access_token
  // @param component_appid: 第三方平台的appid，不传值，则默认一个
  // @return component_access_token
 public static function get_component_access_token($component_appid){

   $third_platform_info = self::get_third_platform($component_appid);


   $component_access_token = $third_platform_info['component_access_token'];

   if ($third_platform_info['expire_time'] < time() || !$component_access_token) {
     $url = "https://api.weixin.qq.com/cgi-bin/component/api_component_token";
     $post_data = array();
     $post_data['component_appid'] = $third_platform_info['appid'];
     $post_data['component_appsecret'] = $third_platform_info['appsecret'];
     $post_data['component_verify_ticket'] = $third_platform_info['component_verify_ticket'];
     $res = json_decode(self::post($url,json_encode($post_data)));
     Log::write('获取component_access_token时候错误信息：',json_encode($res));
     $component_access_token = $res->component_access_token;
     Log::write('获取到的component_access_token：',$component_access_token);

     if ($component_access_token) {
      $expire_time= time() + 6600;
      $update_info = array();
      $update_info['appid'] = $third_platform_info['appid'];
      $update_info['expire_time'] = $expire_time;
      $update_info['component_access_token'] = $component_access_token;
      self::update_third_platform($update_info);
    }else{
      return $res->errcode;
    }
  }

  return $component_access_token;
}
    //3、获取预授权码pre_auth_code,20分钟有效，故要轮询
    // @param component_appid: 第三方平台的appid，不传值，则默认一个
  // @return pre_auth_code
public static function get_pre_auth_code($component_appid){
 $component_appid = self::check_component_appid($component_appid);
 $component_access_token = self::get_component_access_token($component_appid);

 $url = 'https://api.weixin.qq.com/cgi-bin/component/api_create_preauthcode?component_access_token='.$component_access_token;
      // echo $url;
      // exit;
 $post_data = array();
 $post_data['component_appid'] = $component_appid;
 $res = json_decode(self::post($url,json_encode($post_data)));
      // dump($res);
      // exit;
 Log::write('获取pre_auth_code信息：'.json_encode($res));
 $pre_auth_code = $res->pre_auth_code;
 Log::write('获取到的pre_auth_code：',$pre_auth_code);

 if($pre_auth_code) {

 }else{
  Log::write('获取pre_auth_code时候错误信息：',json_encode($res));
  return $res->errcode;
}
return $pre_auth_code;
}
   //获取跳转到授权页的url
    // @param component_appid: 第三方平台的appid，不传值，则默认一个
  // @return url
public static function get_oauth_url($component_appid,$url){
 $retVal = Session::init();
 $customerId= Session::$user['customerId'];
 $component_appid = self::check_component_appid($component_appid);
 $pre_auth_code = self::get_pre_auth_code($component_appid);
     // $component_appid = $third_platform_info['appid'];
 if($url && $url != ''){
  $redirect_uri = C('SERVER_HOST').$url;
}else{
   $redirect_uri = C('SERVER_HOST').'Callback/redirect.json';
   $redirect_uri = $redirect_uri.'&cid='.$customerId.'&third_platform_appid='.$component_appid;
}


 $redirect_uri = urlencode($redirect_uri);
 $url = 'https://mp.weixin.qq.com/cgi-bin/componentloginpage?component_appid='.$component_appid.'&pre_auth_code='. $pre_auth_code.'&redirect_uri='.$redirect_uri;
 return $url;
}
  //4、使用授权码换取公众号的接口调用凭据和授权信息
public static function get_authorizer_info($component_appid,$authorization_code){
 $component_appid = self::check_component_appid($component_appid);
 $component_access_token = self::get_component_access_token($component_appid);
 $url = 'https://api.weixin.qq.com/cgi-bin/component/api_query_auth?component_access_token='.$component_access_token;
 $post_data = array();
 $post_data['component_appid'] = $component_appid;
 $post_data['authorization_code'] = $authorization_code;
 Log::write('get_authorizer_info,post_data信息：'.json_encode($post_data));
 $res = json_decode(self::post($url,json_encode($post_data)));

 $authorization_info = $res->authorization_info;
 if($authorization_info){

  Log::write('获取authorizer_info信息：'.json_encode($authorization_info));
}else{
 $authorization_info = false;
}
Log::write('获取authorizer_info_all信息：'.json_encode($res));
return $authorization_info;
}
  //获取授权方的公众号帐号基本信息
  // @param component_appid: 第三方平台的appid，不传值，则默认一个
   // @param authorizer_appid: 公众号的appid，必传
  // @return json
public static function get_authorization_base_info($component_appid,$authorizer_appid){
  $component_appid = self::check_component_appid($component_appid);
  $component_access_token = self::get_component_access_token($component_appid);

  $url = 'https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_info?component_access_token='.$component_access_token;
  $post_data = array();
  $post_data['component_appid'] = $component_appid;
  $post_data['authorizer_appid'] = $authorizer_appid;
  $res = json_decode(self::post($url,json_encode($post_data)));
  $post_data['component_access_token'] = $component_access_token;
  log::write('参数：'.json_encode($post_data));
     // $authorizer_info = $res->authorizer_info;
     //  if($authorizer_info){

     //      Log::write('获取authorizer_info信息：'.json_encode($authorizer_info));
      // }else{
     //     $authorizer_info = false;
      // }
  Log::write('获取authorizer_info信息：'.json_encode($res));
  return $res;

}
  //获取授权方的选项设置信息
  //该API用于获取授权方的公众号的选项设置信息，如：地理位置上报，语音识别开关，多客服开关。注意，获取各项选项设置信息，需要有授权方的授权，详见权限集说明。
  // @param component_appid: 第三方平台的appid，不传值，则默认一个
  // @param authorizer_appid: 公众号的appid，必传
  // @param option_name: ，选项名称 必传,location_report(地理位置上报选项),voice_recognize（语音识别开关选项）,customer_service（多客服开关选项）
  //return json
public static function get_authorizer_set($component_appid,$authorizer_appid,$option_name){
 $component_appid = self::check_component_appid($component_appid);
 $component_access_token = self::get_component_access_token($component_appid);
 $url = 'https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_option?component_access_token='.$component_access_token;
 $post_data = array();
 $post_data['component_appid'] = $component_appid;
 $post_data['authorizer_appid'] = $authorizer_appid;
 $post_data['option_name'] = $option_name;
 $res = json_decode(self::post($url,json_encode($post_data)));
 log::write('获取'.$option_name.'选项结果：'.json_encode($res));
    // $authorizer_appid = $res->authorizer_appid;
    // $option_value = $res->option_value;

    // if($authorizer_appid){

    // }else{
    //  return $res;
    // }
 return $res;
}

   //设置授权方的选项信息
  //该API用于获取授权方的公众号的选项设置信息，如：地理位置上报，语音识别开关，多客服开关。注意，获取各项选项设置信息，需要有授权方的授权，详见权限集说明。
  // @param component_appid: 第三方平台的appid，不传值，则默认一个
  // @param authorizer_appid: 公众号的appid，必传
  // @param option_name: ，选项名称 必传,location_report(地理位置上报选项),voice_recognize（语音识别开关选项）,customer_service（多客服开关选项）
  // @param option_value ,选项值必传
  //return json,
public static function set_authorizer_option($component_appid,$authorizer_appid,$option_name,$option_value){
 $component_appid = self::check_component_appid($component_appid);
 $component_access_token = self::get_component_access_token($component_appid);
 $url = 'https://api.weixin.qq.com/cgi-bin/component/api_set_authorizer_option?component_access_token='.$component_access_token;
 $post_data = array();
 $post_data['component_appid'] = $component_appid;
 $post_data['authorizer_appid'] = $authorizer_appid;
 $post_data['option_name'] = $option_name;
 $post_data['option_value'] = $option_value;
 $res = json_decode(self::post($url,json_encode($post_data)));
    // $authorizer_appid = $res->authorizer_appid;
    // $option_value = $res->option_value;

    // if($authorizer_appid){

    // }else{
    //  return $res;
    // }
 return $res;
}

  //获取第三方平台信息
public static function get_third_platform($component_appid){
  $retVal = Session::init();
  $customerId= Session::$user['customerId'];
  Session::switchCustomer(0);
  $map  = array();
  $component_appid = self::check_component_appid($component_appid);
  $map['appid'] = $component_appid;

  $third_platform_info = M('ThirdPlatform')->where($map)->find();

    // if(!$third_platform_info){
    //  $third_platform_info = C('third_platform_info');
    // }
  Session::switchCustomer($customerId);
  return $third_platform_info;
}
public static function check_component_appid($component_appid){
 if(!$component_appid){
   $retVal = Session::init();
   $customerId= Session::$user['customerId'];
   Session::switchCustomer(0);
   $map = array();
   $map['name'] = 'default';
   $component_appid = M("ThirdPlatform")->where($map)->getField('appid');
   Session::switchCustomer($customerId);
 }
 return $component_appid;
}
    //更新第三方平台信息
public static function update_third_platform($third_platform_info){
  $retVal = Session::init();
  $customerId= Session::$user['customerId'];
  Session::switchCustomer(0);
  $map = array();
  $map['appid'] = $third_platform_info['appid'];
  M('ThirdPlatform')->where($map)->save($third_platform_info);
  Session::switchCustomer($customerId);
}

//第三方平台用户授权获得code
public static function getOauthByCode($appid,$component_appid,$code,$scope){
    $component_access_token = self::get_component_access_token($component_appid);
    $url = "https://api.weixin.qq.com/sns/oauth2/component/access_token?appid=$appid&code=$code&grant_type=authorization_code&component_appid=$component_appid&component_access_token=$component_access_token";
    $ch = curl_init($url) ;
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true) ; // 获取数据返回
    curl_setopt($ch, CURLOPT_BINARYTRANSFER, true) ; // 在启用 CURLOPT_RETURNTRANSFER 时候将获取数据返回
    $access = curl_exec($ch) ;
    curl_close($ch);
    //Log::write($access);
    $access = json_decode($access);
    if (isset($access->errcode) && $access->errcode != 0) {
        Log::write('oauth error:' . $access->errmsg . $access->errcode);
//      Output::instance()->resultCode(code_access_expired, $access->errmsg);
        return;
    }
    $expiration = time() + ((int)$access->expires_in - 60);
    WeixinApi::setUserOauthToken($access->openid, $access->access_token, $expiration, $access->refresh_token);
    $access->expiration = $expiration;
    return $access;
}
//第三方平台用户授权
public static function getOauthAccessToken($result,$scope,$srcUrl=null){
    log::write("menghuidayiin在WechatThirdPlatForm中.code".$_GET['code']);
    $SERVER_NAME=WeixinApi::getDomainName($result);
    $SERVER_NAME = $SERVER_NAME['SERVER_NAME'];
    $REQUEST_URI=$_SERVER['REQUEST_URI'];
    $appid = $result['appid'];
    $component_appid = $result['third_platform_appid'];
    $code = $_GET['code'];
    if(isset($code)){
        $access = self::getOauthByCode($appid,$component_appid,$code,$scope);
        log::write('mh_打印access'.json_encode($access));
        if ($access && !$access->errcode) {
            return $access;
        } else { //code错误重新获取
            if ($srcUrl){
               $redirectUrl = $srcUrl;
            }else{
                $redirectUrl = urlencode($SERVER_NAME .  preg_replace("/&code=\w+/","",$REQUEST_URI));
            }

            $url= "https://open.weixin.qq.com/connect/oauth2/authorize?appid=$appid&redirect_uri=$redirectUrl&response_type=code&scope=$scope&state=STATE&component_appid=$component_appid#wechat_redirect";

            //如果有传入的跳转url项
            if ($srcUrl){
                $return['code'] = 0;
                $return['msg'] = $url;
                Output::instance()->object($return);
                die;
            }else{
                 redirect($url);
            }
        }
    }else{
        if ($srcUrl){
            $redirectUrl = $srcUrl;
        }else{
            $redirectUrl = urlencode($SERVER_NAME .  preg_replace("/&code=\w+/","",$REQUEST_URI));
        }

        $url= "https://open.weixin.qq.com/connect/oauth2/authorize?appid=$appid&redirect_uri=$redirectUrl&response_type=code&scope=$scope&state=STATE&component_appid=$component_appid#wechat_redirect";
       if ($srcUrl){
            $return['code'] = 0;
            $return['msg'] = $url;
            Output::instance()->object($return);
            die;
        }else{
             redirect($url);
        }
    }
}


    //4：post文件数据
private static function post($url=null,$post_data=null){

  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, $url);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  curl_setopt($curl, CURLOPT_ENCODING, 'gzip,deflate');
  curl_setopt($ch, CURLOPT_POST, 1);
  curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
  curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,false);
  curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,false);

  $output = curl_exec($ch);

  if($output == false){
    echo '<br/>'.curl_error($ch).'<br/>';
    exit();
  }
  curl_close($ch);
  return $output;
}
}
